package algorithm;
//Used in Sentinel Inc.'s Defensive Driver Prototype
//Programmer: John Casey Marr
//Programmer:
//Programmer: 
//Class CS 411 Professional Workforce Development
/**
 * @author John Marr
 */

import gui.obu.ObuDrivingDisplayPanel;
import gui.obu.ObuDrivingDisplayPanelImpl;
import gui.obu.alerts.DistanceAlert;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Calendar;

import database.OBUdata;
import database.OBUdb;

import objects.DistanceLog;
import objects.OBUentry;

public class Distance_Detection{
	
	//Current Distance of object in front of driver
	private double cur_distance;
	//Calculated Safe Driving Distance
	private double calc_safe_distance;
	//Current Speed of Driver for calc_safe_distance
	private int cur_speed;
	
	//Has the driver been maintaing a safe driving distance
	private boolean safe_distance;
	
	//4 meters is average car length
	private double car_length;
	
	//Calendar for getting time values
	private Calendar distance_now;
	
	//Time Start and Stop of Violation
	private long distance_start;
	private long distance_stop;
	private OBUentry myEntry;
	
	private int avg_speed;
	private double min_dist;
	private int iteration;
	
	//GUI Stuff
	private ObuDrivingDisplayPanel window;
	
	public void setWindow(ObuDrivingDisplayPanel window)
	{
		this.window=window;
	}
	
	public Distance_Detection()
	{
		cur_distance=32.0;
		calc_safe_distance=0.0;
		cur_speed=0;
		safe_distance=true;
		car_length=4.0;
		distance_now=Calendar.getInstance();
		distance_start=0;
		distance_stop=0;
		myEntry=new OBUentry();
		avg_speed=0;
		min_dist=999;
		iteration=1;
	}
	
	@SuppressWarnings("deprecation")
	public double getDistance(){
		File distanceFile= new File("C:/Users/Public/Documents/distance.txt");
		FileInputStream fileInput=null;
		BufferedInputStream buffer=null;
		DataInputStream dataInput=null;
		
		double distance=0.0;
		String distance_=new String();
		
		try{
			fileInput= new FileInputStream(distanceFile);
			buffer = new BufferedInputStream(fileInput);
			dataInput= new DataInputStream(buffer);
		
			while(dataInput.available() !=0)
			{
				distance=Double.valueOf(dataInput.readLine());
			}
			fileInput.close();
			buffer.close();
			dataInput.close();
		}
		catch (FileNotFoundException e)
		{
			System.out.println("Could not find file");
		}
		catch (IOException e)
		{
			System.out.println("Could not open IO");
		}
	
		System.out.println("Distance is: " + distance);
		return distance;
	}


	public void compute(OBUdata runtimedb, OBUdb obudatabase, Integer i,Integer driverID)
	{
		System.out.println(i);
		//Step 1:  Collect Driver's Speed
		//cur_speed=obu.getSpeed();
		myEntry.setID(i);
                try {
                        runtimedb.getOBUEntry(myEntry);
                } catch (java.sql.SQLException mysqlex) {
                        System.out.println("Cannot get this entry");
                        return;
                }
		//myEntry.display();
		cur_speed=myEntry.getSpeed();

		//Step 2:  Calculate Safe Driving Distance
		calc_safe_distance=(cur_speed/10)*car_length;

		//Step 3:  Collect Driver's Distance
		cur_distance=getDistance();
		
		if(!((ObuDrivingDisplayPanelImpl)window).getDisplay().isDisposed()) {
			((ObuDrivingDisplayPanelImpl)window).getDisplay().asyncExec(new Runnable() {
				public void run() {
					((ObuDrivingDisplayPanelImpl)window).setFollowingDistance(cur_distance);
				}
			});
		}
		
		//Step 4:  Compare Driver's distance to Calculated Safe Distance
		if((cur_distance<calc_safe_distance) && safe_distance)
		{
			//Alert Driver
			//Alert
			if(window==null)
			{
				System.out.println("Could Not Add Distance Detection Alert");
			}
			else
			{
				if(!((ObuDrivingDisplayPanelImpl)window).getDisplay().isDisposed()) {
					((ObuDrivingDisplayPanelImpl)window).getDisplay().asyncExec(new Runnable() {
						public void run() {
							((ObuDrivingDisplayPanelImpl)window).addAlert(new DistanceAlert(cur_speed,cur_distance,calc_safe_distance));
						}
					});
				}
			}
			//Start Counter
			distance_now.setTimeInMillis(System.currentTimeMillis());
			distance_start=distance_now.getTimeInMillis();
			safe_distance=false;
		}
		if(!safe_distance)
		{
			avg_speed=(cur_speed+avg_speed)/iteration;
			//See if current distance is smaller than min
			//if(min_dist>currentDistance)
			//min_dist=currentDistance;

			iteration++;
		}
		if(cur_distance>calc_safe_distance && !safe_distance)
		{
			//Save Driver stop sign
			distance_now.setTimeInMillis(System.currentTimeMillis());
			distance_stop=distance_now.getTimeInMillis();
			//Set safe_distance to true
			safe_distance=true;
			//Save Driver Infraction
			//Driverprofile.distance(distance_start,distance_stop);
			DistanceLog alpha=new DistanceLog();
			alpha.setStudentID(driverID);
			alpha.setCurrSpeed(avg_speed);
			alpha.setDistance(min_dist);
			alpha.setType(1);
			alpha.setLocationID(1);
			alpha.setDuration(new Integer((int)distance_stop-(int)distance_start));
			try {
				obudatabase.addDistanceLog(alpha);
			} catch (SQLException e) {
				System.out.println("Could Not Add Distance Log: " + e.getMessage());
			}
		}
		if(min_dist>cur_distance)
		{
			min_dist=cur_distance;
		}
	}

}

